//using System;
//using System.Xml;
//using EnvDTE80;
//using JetBrains.ReSharper.Metadata.Access;
//using JetBrains.ReSharper.Metadata.Reader.API;
//using JetBrains.ReSharper.ProjectModel;
//using JetBrains.ReSharper.Psi;
//using JetBrains.ReSharper.UnitTestSupport.PluginInterface;
//using JetBrains.ReSharper.Util;
//using log4net;
//
//namespace JamesKovacs.ReSharper.UnitTestSupport.VstsUnit {
//    [UnitTestCodeExplorer("VstsUnit")]
//    public class VstsUnitCodeExplorer : IUnitCodeExplorer {
//        private static readonly ILog s_Logger = LogManager.GetLogger(typeof(VstsUnitCodeExplorer));
//        private const string VstsUnitTestingAssemblyName = "Microsoft.VisualStudio.QualityTools.UnitTestFramework";
//        private CLRTypeName ignoreAttribute = new CLRTypeName("Microsoft.VisualStudio.TestTools.UnitTesting.IgnoreAttribute");
//        private CLRTypeName testClassAttribute = new CLRTypeName("Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute");
//        private CLRTypeName testMethodAttribute = new CLRTypeName("Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute");
//
//        public VstsUnitCodeExplorer() {
//            VstsUnitSetup.Initialize();
//        }
//
//        public bool IsTestFixture(ITypeElement element) {
//            try {
//                if(element == null) {
//                    return false;
//                }
//                return element.HasAttributeInstance(testClassAttribute, false);
//            } catch(Exception ex) {
//                s_Logger.Error("Exception thrown in IsTestFixture(ITypeElement)", ex);
//                return false;
//            }
//        }
//
//        private bool IsTestFixture(IMetadataTypeInfo typeInfo) {
//            if(typeInfo == null) {
//                throw new ArgumentNullException("typeInfo");
//            }
//            return typeInfo.HasCustomAttribute(testClassAttribute.ClrName);
//        }
//
//        public bool IsTestFixture(CodeClass2 codeClass) {
//            try {
//                if(codeClass == null) {
//                    return false;
//                }
//                foreach(CodeAttribute2 attribute in codeClass.Attributes) {
//                    if(attribute.FullName == testClassAttribute.ClrName) {
//                        return true;
//                    }
//                }
//                return false;
//            } catch(Exception ex) {
//                s_Logger.Error("Exception thrown in IsTestFixture(CodeClass2)", ex);
//                return false;
//            }
//        }
//
//        public bool IsTestMethod(ITypeMember element) {
//            try {
//                if(element == null) {
//                    return false;
//                }
//                return element.HasAttributeInstance(testMethodAttribute, false);
//            } catch(Exception ex) {
//                s_Logger.Error("Exception thrown in IsTestMethod(ITypeMember)", ex);
//                return false;
//            }
//        }
//
//        private bool IsTestMethod(IMetadataMethod method) {
//            if(method == null) {
//                throw new ArgumentNullException("method");
//            }
//            return method.HasCustomAttribute(testMethodAttribute.ClrName);
//        }
//
//        public bool IsTestMethod(CodeFunction2 codeFunction) {
//            try {
//                if(codeFunction == null) {
//                    return false;
//                }
//                foreach(CodeAttribute2 attribute in codeFunction.Attributes) {
//                    if(attribute.FullName == testMethodAttribute.ClrName) {
//                        return true;
//                    }
//                }
//                return false;
//            } catch(Exception ex) {
//                s_Logger.Error("Exception thrown in IsTestFixture(CodeClass2)", ex);
//                return false;
//            }
//        }
//
//        public XmlDocument Explore(IMetadataAssembly assembly) {
//            try {
//                XmlDocument document = new XmlDocument();
//                XmlElement assemblyElement = XmlUtil.CreateElement(document, "Assembly");
//                XmlUtil.CreateAttributeWithValue(assemblyElement, "Name", assembly.AssemblyName.FullName);
//                foreach(IMetadataTypeInfo typeInfo in assembly.GetTypes()) {
//                    if(IsTestFixture(typeInfo)) {
//                        XmlElement classElement = XmlUtil.CreateElement(assemblyElement, "Fixture");
//                        XmlUtil.CreateAttributeWithValue(classElement, "Name", typeInfo.FullyQualifiedName);
//                        if(typeInfo.HasCustomAttribute(ignoreAttribute.ClrName)) {
//                            XmlUtil.CreateAttributeWithValue(classElement, "State", TestFixtureState.IGNORED.ToString());
//                        }
//                        foreach(IMetadataMethod methodInfo in typeInfo.GetMethods()) {
//                            if(IsTestMethod(methodInfo)) {
//                                XmlElement methodElement = XmlUtil.CreateElement(classElement, "Method");
//                                XmlUtil.CreateAttributeWithValue(methodElement, "Name", methodInfo.Name);
//                                if(methodInfo.HasCustomAttribute(ignoreAttribute.ClrName)) {
//                                    XmlUtil.CreateAttributeWithValue(methodElement, "State", TestFixtureState.IGNORED.ToString());
//                                }
//                            }
//                        }
//                    }
//                }
//                return document;
//            } catch(Exception ex) {
//                s_Logger.Error("Exception thrown in Explore(IMetadataAssembly)", ex);
//                return null;
//            }
//        }
//
//        public bool Vote(IMetadataAssembly assembly) {
//            try {
//                foreach(AssemblyReference reference in assembly.ReferencedAssembliesNames) {
//                    if(string.Compare(reference.AssemblyName.Name, VstsUnitTestingAssemblyName, StringComparison.InvariantCultureIgnoreCase) == 0) {
//                        return true;
//                    }
//                }
//                return false;
//            } catch(Exception ex) {
//                s_Logger.Error("Exception thrown in Vote(IMetadataAssembly)", ex);
//                return false;
//            }
//        }
//
//        public bool Vote(IProject project) {
//            try {
//                foreach(IAssemblyReference reference in project.GetAssemblyReferences()) {
//                    if(string.Compare(reference.Name, VstsUnitTestingAssemblyName, StringComparison.InvariantCultureIgnoreCase) == 0) {
//                        return true;
//                    }
//                }
//                return false;
//            } catch(Exception ex) {
//                s_Logger.Error("Exception thrown in Vote(IProject)", ex);
//                return false;
//            }
//        }
//    }
//}